package cn.thinkluck.pattern.factory.method;

import cn.thinkluck.pattern.factory.method.resource.IResourceFactory;
import cn.thinkluck.pattern.factory.simple.Resource;
import cn.thinkluck.pattern.factory.simple.ResourceLoaderException;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 资源加载
 *
 * @Author liutao
 * @DateTime 2024/7/15 下午10:27
 */
public class ResourceLoader {
    private IResourceFactory iResourceFactory;
    private static final Map<String, IResourceFactory> resourceFactoryCache = new HashMap<>(8);

    /*
    //版本2
    将工厂实现放到map中
    static {
        {
            resourceFactoryCache.put("file", new FilepathResourceFactory());
            resourceFactoryCache.put("http", new HttpResourceFactory());
            resourceFactoryCache.put("ftp", new FtpResourceFactory());
            resourceFactoryCache.put("classpath", new ClasspathResourceFactory());
        }
    }*/
    //版本3 使用配置文件方式，更加灵活
    //1. 完全满足开闭原则，对修改关闭，只需要扩展配置文和工厂实现类
    static {
        //读取配置文件
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("ResourceLoader.properties");
        if (inputStream != null) {
            try {
                Properties properties = new Properties();
                properties.load(inputStream);
                //遍历配置文件
                for (String key : properties.stringPropertyNames()) {
                    //配置文件中的实现类全限定名
                    String property = properties.getProperty(key);
                    resourceFactoryCache.put(key, (IResourceFactory) Class.forName(property).newInstance());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用工厂方法模式的资源加载示例
     *
     * @param url 资源url file:// http:// ftp:// classpath:
     * @return 资源
     */
    public Resource load(String url) {
        //1. 根据url获取前缀
        String prefix = getPrefix(url);
        //版本2
        iResourceFactory = resourceFactoryCache.get(prefix);
        //2. 根据前缀加载资源
        /* 版本1
        switch (prefix) {
            case "file":
                iResourceFactory = new FilepathResourceFactory();
                break;
            case "http":
                iResourceFactory = new HttpResourceFactory();
                break;
            case "ftp":
                iResourceFactory = new FtpResourceFactory();
                break;
            case "classpath":
                iResourceFactory = new ClasspathResourceFactory();
                break;
            default:
                throw new ResourceLoaderException("url prefix is not support");
        }*/
        return iResourceFactory.create(url);
    }

    private String getPrefix(String url) {
        if (url == null || url.isEmpty()) {
            throw new ResourceLoaderException("url is null");
        }
        String[] split = url.split(":");
        return split[0];
    }
}
